package com.hcc.gateway.app.filter;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.hcc.gateway.app.constant.HccGatewayAppConstant;
import com.hcc.gateway.app.utils.ParamConvertUtils;
import com.hcc.gateway.domain.enums.ApiParamMappingTypeEnum;
import com.hcc.gateway.domain.enums.ContentTypeEnum;
import com.hcc.gateway.domain.po.ApiConfigPo;
import com.hcc.gateway.domain.vo.ApiParamMappingVo;
import com.hcc.gateway.netty.context.GatewayExchange;
import com.hcc.gateway.netty.context.ReqContext;
import com.hcc.gateway.netty.filter.GatewayFilter;
import com.hcc.gateway.netty.filter.GatewayFilterChain;
import com.hcc.gateway.service.ApiParamMappingService;
import io.netty.handler.codec.http.HttpMethod;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

/**
 * ReqConvertFilter
 *
 * @author shengjun.hu
 * @date 2021/12/30
 */
@Slf4j
@Component
public class ReqParamConvertFilter implements GatewayFilter {

    @Autowired
    private ApiParamMappingService apiParamMappingService;

    @Override
    public int getOrder() {
        return 230;
    }

    @Override
    public void filter(GatewayExchange exchange, GatewayFilterChain chain) {
        log.info("进入ReqParamConvertFilter !");
        ReqContext reqContext = exchange.getReqContext();
        HttpMethod method = reqContext.getMethod();

        ApiConfigPo apiConfig = exchange.getAttributeByName(HccGatewayAppConstant.HCC_API_CONFIG, ApiConfigPo.class);
        ApiParamMappingVo apiParamMapping = apiParamMappingService.findApiParamMappingByApiConfig(apiConfig.getId(), ApiParamMappingTypeEnum.REQ);
        if (apiParamMapping == null) {
            // 兼容为空的情况
            apiParamMapping = new ApiParamMappingVo();
            apiParamMapping.setChildren(Collections.emptyList());
        }

        Object convertResult = null;
        if (HttpMethod.GET.equals(method) || HttpMethod.DELETE.equals(method)) {
            if (CollectionUtil.isEmpty(reqContext.getQueryParams()) || !ParamConvertUtils.hasParamMapping(apiParamMapping)) {
                chain.filter(exchange);
                return;
            }
            convertResult = ParamConvertUtils.convertParam(reqContext.getQueryParams(), apiParamMapping.getChildren());
        } else if (HttpMethod.POST.equals(method) || HttpMethod.PUT.equals(method)) {
            if (ContentTypeEnum.FORM_URLENCODED.beContained(reqContext.getContentType())) {
                convertResult = ParamConvertUtils.convertParam(reqContext.getFormData(), apiParamMapping.getChildren());
            } else if (ContentTypeEnum.JSON.beContained(reqContext.getContentType())) {
                String stringBody = reqContext.getStringBody();
                if (JSONUtil.isJsonArray(stringBody)) {
                    List<Object> jsonArray = JSON.parseArray(stringBody);
                    convertResult = ParamConvertUtils.convertParamArr(jsonArray, apiParamMapping.getChildren());
                } else {
                    Map<String, Object> jsonObject = JSON.parseObject(stringBody);
                    convertResult = ParamConvertUtils.convertParam(jsonObject, apiParamMapping.getChildren());
                }
            }
        } else {
            throw new RuntimeException(String.format("网关暂不支持的方法：[%s]", method.name()));
        }

        log.info("转换结果：{}", JSON.toJSONString(convertResult));
        exchange.addAttribute(HccGatewayAppConstant.HCC_REQ_PARAM, convertResult);

        chain.filter(exchange);
    }

}
